package aexp.customview;

import android.content.Context;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.widget.ImageView;
import java.util.ArrayList;
import java.util.Map;

public class AlarmingView extends ImageView {
  private boolean alarming = false;
  static FlashingThread flashingThread = null;
  static final String LOG_TAG = "AlarmingView";

  public AlarmingView(Context context) {
    super( context );
	if( flashingThread == null )
		flashingThread = new FlashingThread();
  }

  public AlarmingView(Context context, AttributeSet attrs, Map inflateParams) {
	super( context, attrs, inflateParams );
	if( flashingThread == null )
		flashingThread = new FlashingThread();
  }

  public AlarmingView( Context context, 
					AttributeSet attrs, 
					Map inflateParams, 
					int defStyle ) {
	super( context, attrs, inflateParams, defStyle );
	if( flashingThread == null )
		flashingThread = new FlashingThread();
  }

  public void setAlarming( boolean alarming ) {
	this.alarming = alarming;
  }
  
  public void setState( boolean state ) {
    int imageResource = state ? R.drawable.exc : R.drawable.exc_empty;
	setImageResource( imageResource );
	invalidate();
  }

/**
  * This is called before the first onDraw(). We make sure that FlashingThread
  * exists and running and the FlashingThread knows about us.
  */
  protected void onAttachedToWindow() {
	super.onAttachedToWindow();
	Log.d( LOG_TAG, "onAttachedWindow" );
	if( alarming ) {
	  flashingThread.addView( this );
	  flashingThread.start();
    }
  }

/**
  * This is called after the view loses its drawing surface. We make sure that
  * this view is removed from FlashingThread and even stop FlashingThread if
  * there are no more views associated to FlashingThread.
  */
  protected void onDetachedFromWindow() {
	super.onDetachedFromWindow();
	Log.d( LOG_TAG, "onDetachedFromWindow" );
	if( alarming ) {
	  flashingThread.removeView( this );
	  flashingThread.stop();
    }
  }

  class FlashingThread implements Runnable {
	ArrayList<AlarmingView> viewList = new ArrayList<AlarmingView>();
	Handler handler = new Handler();
    boolean state = false;
    boolean run = false;
    static final long PERIOD = 1000L;
    static final String LOG_TAG = "FlashingThread";

	public void addView( AlarmingView alarmingView ) {
	  synchronized( viewList ) {
		if( !viewList.contains( alarmingView ) )
			viewList.add( alarmingView );
	  }
	}

	public void removeView( AlarmingView alarmingView ) {
	  synchronized( viewList ) {
		int index = viewList.indexOf( alarmingView );
		if( index < 0 )
			return;
		viewList.remove( index );
	  }
	}

    public void start() {
	  if( !run ) {
		handler.postDelayed( this, PERIOD );
		run = true;
	  }
    }

	public void stop() {
	  if( viewList.size() == 0 )
	  		run = false;
    }

    public void run() {
	  state = !state;
      synchronized( viewList ) {
		for( int i = 0 ; i < viewList.size() ; ++i ) {
		    AlarmingView alarmingView = viewList.get( i );
			alarmingView.setState( state );
		}
      }
	  if( run )
		handler.postDelayed( this, PERIOD );
	}
  }

}
